﻿using Spritehand.FarseerHelper;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;


namespace Spritehand.PhysicsHelper.Demos.UWP
{
    /// <summary>
    /// This is the main page which gets physics objects added onto it
    /// </summary>
    public sealed partial class MainPage : Page
    {
        int _collisionGroupNum = 10; // differentiates collision groups
        DateTime _dtLastFpsUpdate;
        int _collisionCount = 0;
        double _addPosX = 0;
        List<PhysicsSprite> _sprites = new List<PhysicsSprite>();
        SoundMain _soundAddItem, _soundHit;

        public bool DebugMode
        {
            get
            {
                return cnvGame.DebugMode;
            }
            set
            {
                cnvGame.DebugMode = !cnvGame.DebugMode;
            }
        }

        public MainPage()
        {
            this.InitializeComponent();

            cnvGame.TimerLoop += new PhysicsCanvas.TimerLoopHandler(cnvGame_TimerLoop);
            cnvGame.Collision += new PhysicsCanvas.CollisionHandler(cnvGame_Collision);
            cnvGame.ScaleToObject(cnvGameOuter);
            _soundAddItem = new SoundMain(cnvGame, "Assets/sounds/trampoline.wav", 3, 0);
            _soundHit = new SoundMain(cnvGame, "Assets/sounds/hit.wav", 5, 0);
        }

        void cnvGame_Collision(PhysicsSprite sprite1, PhysicsSprite sprite2, FarseerPhysics.Dynamics.Contacts.Contact contact)
        {
            // this event is fired for each sprite to sprite collision
            // taking into account CollisionGroup.
            _collisionCount++;


            if (PhysicsUtilities.GetMaxCollisionForce(contact) > 0.3)
                _soundHit.Play();
        }

        void cnvGame_TimerLoop(object source)
        {
            // this event is fired for EACH Timer tick of the simulation.
            if ((DateTime.Now - _dtLastFpsUpdate).TotalMilliseconds > 1000)
            {
                tbStatus.Text = String.Format("{0} fps with {1} UIElements, {2} bodies, {3} joints, {4} collisions", cnvGame.LastFPS, cnvGame.Children.Count(), cnvGame.Simulator.BodyList.Count, cnvGame.Simulator.JointList.Count, _collisionCount);
                _dtLastFpsUpdate = DateTime.Now;
                _collisionCount = 0;
            }
        }


        public List<PhysicsSprite> AddAnItem(UserControl uc)
        {
            _soundAddItem.Play();

            List<PhysicsSprite> spritesAdded = cnvGame.AddPhysicsUserControl(uc, _addPosX, 0, _collisionGroupNum);
            _sprites.AddRange(spritesAdded);



            _collisionGroupNum++;

            _addPosX += 200;
            if (_addPosX > 1100)
                _addPosX = 0;

            return spritesAdded;
        }

        public void DeleteAllStuff()
        {
            List<PhysicsSprite> physicsList = cnvGame.PhysicsObjects.Values.ToList();
            for (int i = physicsList.Count - 1; i >= 0; i--)
            {
                // keep the ground and walls!
                PhysicsSprite spr = physicsList[i];

                if (spr.Name != "ground" && (spr.Name.StartsWith("wall") == false))
                    cnvGame.DeletePhysicsObject(spr.Name);
            }
        }

        private void btnAddBlock_Click(object sender, RoutedEventArgs e)
        {
            ucBlock block = new ucBlock();
            AddAnItem(block);
        }

        private void btnAddRagdoll_Click(object sender, RoutedEventArgs e)
        {
            ucRagDoll doll = new ucRagDoll();
            AddAnItem(doll);
        }

        private void btnAddTruck_Click(object sender, RoutedEventArgs e)
        {
            ucTruck truck = new ucTruck();
            AddAnItem(truck);
        }

        private void btnAddSmiley_Click(object sender, RoutedEventArgs e)
        {
            ucSmiley smiley = new ucSmiley();
            AddAnItem(smiley);

            // this shows how we can start storyboards defined inside a physics sprite.
            smiley.MoveEyes.Begin();
        }

        private void cbxDebug_Click(object sender, RoutedEventArgs e)
        {
            // show debug outlines
            DebugMode = !DebugMode;

        }

        private void btnClear_Click(object sender, RoutedEventArgs e)
        {
            DeleteAllStuff();
        }
    }
}
